package com.arrogames.util {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.utils.getDefinitionByName;
	
	import mx.logging.Log;
	
	public class AbstractPreloader extends MovieClip {
		
		//resource location: http://subtlepatterns.com/3px-tile/
		[Embed(source="../../../../resources/preloader/darksquaretiles.png", mimeType="image/png")]
		private var BackgroundTile:Class;
		
		[Embed(source="../../../../resources/preloader/arrogames.png", mimeType="image/png")]
		private var LogoImage:Class;
		
		private static const FRAME_WIDTH:int = 800; //corresponds to the [SWF] tag in Main.as
		private static const FRAME_HEIGHT:int = 450; //corresponds to the [SWF] tag in Main.as
		private static const BAR_WIDTH:int = 600;
		private static const BAR_HEIGHT:int = 50;
		
		private static const BORDER_COLOR:uint = 0x000000;
		private static const FILL_COLOR:uint = 0x00ff00;
		private static const TEXT_COLOR:uint = 0xffffff;
		
		private var barDimension:Rectangle;
		
		private var progressBorder:Shape;
		private var progressBar:Shape;
		private var progressDisplay:TextField;

		private var arroLogo:DisplayObject;
		
		public function AbstractPreloader() {
			var barWidth:Number = BAR_WIDTH;
			var barHeight:Number = BAR_HEIGHT;
			
			barDimension = new Rectangle(
				FRAME_WIDTH/2 - barWidth/2,
				FRAME_HEIGHT/2 - barHeight/2,
				barWidth,
				barHeight
			);
			
			addEventListener(Event.ENTER_FRAME, checkFrame);
			loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
			loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError);
			
			createLoader();
		}
		
		private function createLoader():void {
			createBackground();
			
			
			arroLogo = createLogo();
			progressBorder = createBorder();
			progressBar = createFill();
			progressDisplay = createTextDisplay();
			
			addChild(progressBorder);
			addChild(progressBar);
			addChild(progressDisplay);
			addChild(arroLogo);
		}
		
		private function createLogo():DisplayObject {
			var logo:Bitmap = new LogoImage() as Bitmap; //625*108
			logo.x = barDimension.x + (barDimension.width/2) - logo.width/2;
			logo.y = barDimension.y - logo.height - 10;
			
			return logo;
		}
		
		private function createBackground():void {
			
			var tile:Bitmap = new BackgroundTile() as Bitmap;
			var bmd:BitmapData = tile.bitmapData.clone();
			
			this.graphics.clear();
			this.graphics.beginBitmapFill(bmd);
			this.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			this.graphics.endFill();
		}
		
		private function createTextDisplay():TextField {
			var textField:TextField = new TextField();
			textField.text = "0%";
			textField.textColor = TEXT_COLOR;
			textField.x = barDimension.x + (barDimension.width/2) - 10;
			textField.y = barDimension.y + barDimension.height + 10;
			return textField;
		}
		
		private function createBorder():Shape {
			var rectangle:Shape = new Shape;
			rectangle.x = barDimension.x;
			rectangle.y = barDimension.y;
			rectangle.graphics.lineStyle(1, BORDER_COLOR);
			rectangle.graphics.drawRect(0, 0, barDimension.width, barDimension.height);
			return rectangle;
		}
		
		private function createFill():Shape {
			var rectangle:Shape = new Shape; 
			rectangle.x = barDimension.x+2;
			rectangle.y = barDimension.y+2;
			rectangle.graphics.beginFill(FILL_COLOR);
			rectangle.graphics.lineStyle(1, FILL_COLOR);
			rectangle.graphics.drawRect(0, 0, barDimension.width-4, barDimension.height-4);
			rectangle.graphics.endFill();
			return rectangle;
		}
		
		private function ioError(e:IOErrorEvent):void {
			trace(e.text);
		}
		
		private function progress(e:ProgressEvent):void {
			var ratio:Number = e.bytesLoaded / e.bytesTotal;
			var ratioText:String = int(ratio*100)+"%";
			progressBar.width = (barDimension.width-4) * ratio;
			progressDisplay.text = ratioText;
		}
		
		private function checkFrame(e:Event):void {
			if (currentFrame == totalFrames) {
				stop();
				loadingFinished();
			}
		}
		
		private function loadingFinished():void {
			removeEventListener(Event.ENTER_FRAME, checkFrame);
			loaderInfo.removeEventListener(ProgressEvent.PROGRESS, progress);
			loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError);
			
			removeChild(progressBorder);
			removeChild(progressBar);
			removeChild(progressDisplay);
			removeChild(arroLogo);
			
			this.graphics.clear();
			
			startup();
		}
		
		private function startup():void {
			var clazz:Class = getDefinitionByName(getDefintionName()) as Class;
			addChild(new clazz());
		}
		
		protected function getDefintionName():String {
			throw new Error("Abstract function getDefintionName():String; you must override this!");
			return null;
		}
	}
}